﻿using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Abp.UI;
using ARchGL.Platform.Authorization.Users;
using ARchGL.Platform.Electrocar.Application.Dto;
using ARchGL.Platform.Electrocar.Core;
using ARchGL.Platform.Utils;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace ARchGL.Platform.Electrocar.Application
{
    /// <summary>
    /// 文件 实现
    /// </summary>
    public class FilesAppService : BaseService
    {
        private readonly IRepository<FileDirectorys, Guid> fileDirectorysRepository;
        private readonly IRepository<Files, Guid> filesRepository;

        private readonly UserManager userManager;

        public FilesAppService(IRepository<FileDirectorys, Guid> _fileDirectorysRepository, IRepository<Files, Guid> _filesRepository,
            UserManager _userManager)
        {
            fileDirectorysRepository = _fileDirectorysRepository;
            filesRepository = _filesRepository;
            userManager = _userManager;
        }

        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreateFileDirectorys(FileDirectorysDto input)
        {
            var directorysList = await fileDirectorysRepository.GetAllListAsync(x => x.ProjectId == input.ProjectId && 
                                                                                x.ParentId == input.ParentId && 
                                                                                x.Name == input.Name );
            if(0 != directorysList.Count()) throw new UserFriendlyException("目录已存在，请重新输入");
            var entity = ObjectMapper.Map<FileDirectorys>(input);
            entity.CreationTime = DateTime.Now;
            await fileDirectorysRepository.InsertAsync(entity);
        }

        /// <summary>
        /// 编辑目录名称与排序
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task ModifyFileDirectorys(FileDirectorysDto input)
        {
            var entity = await fileDirectorysRepository.GetAsync(input.Id);
            if (entity == null) throw new UserFriendlyException("目录不存在，请重新输入");
            entity.Name = input.Name;
            if (input.Sort > 0) entity.Sort = input.Sort;
            await fileDirectorysRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除目录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task RemoveFileDirectorys(EntityDto<Guid> input)
        {
            var entity = await fileDirectorysRepository.GetAsync(input.Id);
            if (entity == null) throw new UserFriendlyException("目录不存在，请重新输入");

            var fileCount = await filesRepository.CountAsync(x => x.FileDirectoryId == input.Id);
            if (fileCount > 0) throw new UserFriendlyException("当前目录存在文件不能移除");

            await fileDirectorysRepository.DeleteAsync(entity);
        }

        /// <summary>
        /// 获取文件目录-分页数据集合
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<FileDirectorysDto>> QueryFileDirectorysPagedList(FileDirectorysInput input)
        {
            var query = fileDirectorysRepository.GetAll()
                        .Where(x => x.ProjectId == input.ProjectId)
                        .WhereIf(!input.Keywords.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Keywords));

            var result = await query.OrderByDescending(x => x.CreationTime).PageByAsync(input);

            return new PagedResultDto<FileDirectorysDto>(query.Count(),
                ObjectMapper.Map<List<FileDirectorysDto>>(query));
        }

        /// <summary>
        /// 创建文件
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Guid> CreateFiles(FilesDto input)
        {
            var filesList = filesRepository.GetAllList(x => x.FileDirectoryId == input.FileDirectoryId && x.ProjectId == input.ProjectId).ToList();
            var sameNameList = from Files file in filesList where file.Name == input.Name select file;
            var fileName = ""; //文件名
            var suffixName = ""; //文件后缀名
            if (-1 != input.Name.LastIndexOf("."))
            {
                fileName = input.Name.Substring(0, input.Name.LastIndexOf(".")); //获取文件名
                suffixName = input.Name.Substring(input.Name.LastIndexOf("."), (input.Name.Length - input.Name.LastIndexOf("."))); //获取扩展名
            }

            
            if (0 != sameNameList.Count())
            {
                var i = 1;
                if (string.Empty != fileName && string.Empty != suffixName) input.Name = fileName;
                while (true)
                {

                    if (0 == (from Files file in filesList where file.Name == $"{input.Name}({i}){suffixName}"  select file).Count())
                    {
                        break;
                    }
                    i++;
                }
                input.Name += $"({i}){suffixName}";
            }
            var entity = ObjectMapper.Map<Files>(input);
            entity.CreatorUserName = userManager.UserName;
            await filesRepository.InsertAsync(entity);
            return entity.Id;
        }

        /// <summary>
        /// 修改文件/移动至指定目录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task ModifyFiles(FilesDto input)
        {
            var entity = await filesRepository.GetAsync(input.Id);
            if (entity == null) throw new UserFriendlyException("文件不存在，请重新输入");
            entity.Name = input.Name;
            //entity.FileDirectoryId = input.FileDirectoryId;
            if (input.FileDirectoryId != Guid.Empty) entity.FileDirectoryId = input.FileDirectoryId;
            await filesRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 移动文件到指定目录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task MoveToDirectory(FilesInput input)
        {
            if (!input.FileDirectoryId.HasValue) throw new UserFriendlyException("文件目录不存在，请重新输入");

            var result = filesRepository.GetAll().WhereIf(input.FileIdList.Any(), x => input.FileIdList.Contains(x.Id));
            foreach (var item in result)
            {
                item.FileDirectoryId = input.FileDirectoryId.Value;
                await filesRepository.UpdateAsync(item);
            }
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task RemoveFiles(EntityDto<List<Guid>> input)
        {
            foreach (var item in input.Id)
            {
                var entity = await filesRepository.GetAsync(item);
                if (entity == null) throw new UserFriendlyException("文件不存在，请重新输入");
                await filesRepository.DeleteAsync(entity);
            }
        }

        /// <summary>
        /// 获取文件-分页数据集合
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<FilesDto>> QueryFilesPagedList(FilesInput input)
        {
            var query = filesRepository.GetAll()
                        .WhereIf(input.FileDirectoryId.HasValue, x => x.FileDirectoryId == input.FileDirectoryId)
                        .Where(x => x.ProjectId == input.ProjectId)
                        .WhereIf(input.FileIdList.Any(), x => input.FileIdList.Contains(x.Id))
                        .WhereIf(!input.Keywords.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Keywords) || x.Url.Contains(input.Keywords));

            var result = await query.OrderByDescending(x => x.CreationTime).PageByAsync(input);

            return new PagedResultDto<FilesDto>(query.Count(),
                ObjectMapper.Map<List<FilesDto>>(result));
        }
    }
}
